package com.rnkrsoft.suyan.config.server.services.impl;

import com.rnkrsoft.framework.orm.Pagination;
import com.rnkrsoft.suyan.config.internal.enums.EnvironmentTypeEnum;
import com.rnkrsoft.suyan.config.internal.enums.MachineStatusEnum;
import com.rnkrsoft.suyan.config.internal.enums.OperateObjectEnum;
import com.rnkrsoft.suyan.config.internal.enums.OperateTypeEnum;
import com.rnkrsoft.suyan.config.protocol.v2.ConfigResponseCode;
import com.rnkrsoft.suyan.config.server.config.dao.*;
import com.rnkrsoft.suyan.config.server.config.bo.*;
import com.rnkrsoft.suyan.config.server.config.entity.*;
import com.rnkrsoft.suyan.config.server.services.logger.services.LoggerService;
import com.rnkrsoft.suyan.config.server.services.machine.domains.*;
import com.rnkrsoft.suyan.config.server.services.machine.services.MachineService;
import com.rnkrsoft.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.doc.data.item.OptionItem;
import java.util.List;
import java.util.UUID;

/**
 * Created by woate on 2018/6/18.
 */
@Service
public class MachineServiceImpl implements MachineService {
    @Autowired
    ProjectInfoDAO projectDAO;
    @Autowired
    VersionInfoDAO versionInfoDAO;
    @Autowired
    EnvironmentInfoDAO environmentDAO;
    @Autowired
    MachineInfoDAO machineDAO;
    @Autowired
    ParamInfoDAO paramInfoDAO;
    @Autowired
    FileInfoDAO fileInfoDAO;
    @Autowired
    LoggerService loggerService;

    @Override
    public ToUpdateMachineResponse toUpdate(ToUpdateMachineRequest request) {
        ToUpdateMachineResponse response = new ToUpdateMachineResponse();
        MachineInfoEntity machineEntity = machineDAO.selectByPrimaryKey(request.getMachineId());
        if (machineEntity == null) {
            response.updateResult(ConfigResponseCode.NO_DATA);
            return response;
        }
        EnvironmentInfoEntity environmentEntity = environmentDAO.selectByPrimaryKey(machineEntity.getEnvironmentId());
        if (environmentEntity == null) {
            response.updateResult(ConfigResponseCode.NO_DATA);
            return response;
        }
        VersionInfoEntity versionInfoEntity = versionInfoDAO.selectByPrimaryKey(environmentEntity.getVersionId());
        if (versionInfoEntity == null) {
            response.updateResult(ConfigResponseCode.NO_DATA);
            return response;
        }
        ProjectInfoEntity projectInfoEntity = projectDAO.selectByPrimaryKey(versionInfoEntity.getProjectId());
        if (projectInfoEntity == null) {
            response.updateResult(ConfigResponseCode.NO_DATA);
            return response;
        }
        response.setMachineId(machineEntity.getMachineId());
        response.setProject(projectInfoEntity.getProjectDesc() + "(" + projectInfoEntity.getGroupId() + ":" + projectInfoEntity.getArtifactId() + ":" + versionInfoEntity.getVersion() + ")");
        response.setEnvironment(environmentEntity.getEnvironmentName() + "(" + EnvironmentTypeEnum.valueOfCode(environmentEntity.getEnvironmentType()).getDesc() + ")");
        response.setMachineName(machineEntity.getMachineName());
        response.setMachineDesc(machineEntity.getMachineDesc());
        response.setSecurityKey(machineEntity.getSecurityKey());
        return response;
    }

    @Override
    public UpdateMachineResponse update(UpdateMachineRequest request) {
        UpdateMachineResponse response = new UpdateMachineResponse();
        MachineInfoEntity machineEntity = machineDAO.selectByPrimaryKey(request.getMachineId());
        if (machineEntity == null) {
            response.updateResult(ConfigResponseCode.NO_DATA);
            return response;
        }
        machineEntity.setMachineName(request.getMachineName());
        machineEntity.setMachineDesc(request.getMachineDesc());

        loggerService.writeLog(OperateObjectEnum.MACHINE, request.getMachineId(), OperateTypeEnum.UPDATE, request.getLoginUserId(), request.getLoginUserName());

        machineDAO.updateByPrimaryKeySelective(machineEntity);
        return response;
    }

    @Override
    public DeleteMachineResponse delete(DeleteMachineRequest request) {
        DeleteMachineResponse response = new DeleteMachineResponse();
        MachineInfoEntity machineEntity = machineDAO.selectByPrimaryKey(request.getMachineId());
        if (machineEntity == null) {
            response.updateResult(ConfigResponseCode.NO_DATA);
            return response;
        }
        loggerService.writeLog(OperateObjectEnum.MACHINE, request.getMachineId(), OperateTypeEnum.UPDATE, request.getLoginUserId(), request.getLoginUserName());

        machineDAO.deleteByPrimaryKey(request.getMachineId());
        paramInfoDAO.deleteAnd(ParamInfoEntity.builder().machineId(request.getMachineId()).build());
        fileInfoDAO.deleteAnd(FileInfoEntity.builder().machineId(request.getMachineId()).build());
        return response;
    }

    @Override
    public ViewMachineResponse view(ViewMachineRequest request) {
        ViewMachineResponse response = new ViewMachineResponse();
        MachineInfoEntity machineEntity = machineDAO.selectByPrimaryKey(request.getMachineId());
        if (machineEntity == null) {
            response.updateResult(ConfigResponseCode.NO_DATA);
            return response;
        }
        EnvironmentInfoEntity environmentEntity = environmentDAO.selectByPrimaryKey(machineEntity.getEnvironmentId());
        if (environmentEntity == null) {
            response.updateResult(ConfigResponseCode.NO_DATA);
            return response;
        }
        VersionInfoEntity versionInfoEntity = versionInfoDAO.selectByPrimaryKey(environmentEntity.getVersionId());
        if (versionInfoEntity == null) {
            response.updateResult(ConfigResponseCode.NO_DATA);
            return response;
        }
        ProjectInfoEntity projectInfoEntity = projectDAO.selectByPrimaryKey(versionInfoEntity.getProjectId());
        if (projectInfoEntity == null) {
            response.updateResult(ConfigResponseCode.NO_DATA);
            return response;
        }
        response.setMachineId(machineEntity.getMachineId());
        response.setProject(projectInfoEntity.getProjectDesc() + "(" + projectInfoEntity.getGroupId() + ":" + projectInfoEntity.getArtifactId() + ":" + versionInfoEntity.getVersion() + ")");
        response.setEnvironment(environmentEntity.getEnvironmentName() + "(" + EnvironmentTypeEnum.valueOfCode(environmentEntity.getEnvironmentType()).getDesc() + ")");
        response.setMachineName(machineEntity.getMachineName());
        response.setMachineDesc(machineEntity.getMachineDesc());
        response.setSecurityKey(machineEntity.getSecurityKey());
        return response;
    }

    @Override
    public QueryMachineResponse query(QueryMachineRequest request) {
        QueryMachineResponse response = new QueryMachineResponse();
        Pagination<QueryMachineInfoBO> pagination = new Pagination<QueryMachineInfoBO>(request.getPagination().getPageSize(), request.getPagination().getPageNo());
        if (StringUtils.isNotBlank(request.getProjectId())) {
            pagination.getParams().put("projectId", request.getProjectId());
        }
        if (StringUtils.isNotBlank(request.getMachine())) {
            pagination.getParams().put("machineName", request.getMachine());
        }
        if (StringUtils.isNotBlank(request.getMachineDesc())) {
            pagination.getParams().put("machineName", request.getMachine());
        }
        machineDAO.selectMachinePage(pagination);
        response.getPagination().setPageSize(request.getPagination().getPageSize());
        response.getPagination().setPageNo(request.getPagination().getPageNo());
        response.getPagination().setTotal(pagination.getTotal());
        response.getPagination().setPageNum(pagination.getPageNum());
        for (QueryMachineInfoBO record : pagination.getRecords()) {
            response.addRecord(QueryMachineRecord.builder()
                            .machineId(record.getMachineId())
                            .projectName(record.getGroupId() + ":" + record.getArtifactId() + ":" + record.getVersion())
                            .environmentName(record.getEnvironmentName())
                            .environmentType(record.getEnvironmentType())
                            .machineName(record.getMachineName())
                            .build()
            );
        }
        return response;
    }

    @Override
    public FetchMachineResponse fetch(FetchMachineRequest request) {
        FetchMachineResponse response = new FetchMachineResponse();
        List<FetchMachineBO> fetchMachines = machineDAO.fetchMachine(MachineStatusEnum.NORMAL.getCode());
        for (FetchMachineBO fetchMachineBO : fetchMachines) {
            String machineName = fetchMachineBO.getGroupId() + ":" + fetchMachineBO.getArtifactId() + ":" + fetchMachineBO.getVersion()
                    + "    " + fetchMachineBO.getEnvironmentName() + "(" + EnvironmentTypeEnum.valueOfCode(fetchMachineBO.getEnvironmentType()).getDesc() + ")"
                    + "    " + fetchMachineBO.getMachineName();
            response.addItem(OptionItem.builder().text(machineName).value(fetchMachineBO.getMachineId()).build());
        }
        return response;
    }

    @Override
    public GenerateSecurityKeyResponse generateSecurityKey(GenerateSecurityKeyRequest request) {
        GenerateSecurityKeyResponse response = new GenerateSecurityKeyResponse();
        MachineInfoEntity machineInfoEntity = MachineInfoEntity.builder()
                .machineId(request.getMachineId())
                .securityKey(UUID.randomUUID().toString())
                .build();
        machineDAO.updateByPrimaryKeySelective(machineInfoEntity);
        return response;
    }

    @Override
    public ListMachineByProjectResponse listMachineByProject(ListMachineByProjectRequest request) {
        ListMachineByProjectResponse response = new ListMachineByProjectResponse();
        List<ListMachineInfoByProjectBO> listMachines = machineDAO.listMachineByProject(request.getProjectId());
        for (ListMachineInfoByProjectBO record : listMachines) {
            response.getMachines().add(ListMachineByProjectRecord.builder()
                            .environmentType(record.getEnvironmentType())
                            .environmentName(record.getEnvironmentName())
                            .environmentDesc(record.getEnvironmentDesc())
                            .machineName(record.getMachineName())
                            .machineDesc(record.getMachineDesc())
                            .paramCount(record.getParamCount())
                            .fileCount(record.getFileCount())
                            .build()
            );
        }
        return response;
    }

    @Override
    public ListMachineByEnvironmentResponse listMachineByEnvironment(ListMachineByEnvironmentRequest request) {
        ListMachineByEnvironmentResponse response = new ListMachineByEnvironmentResponse();
        List<ListMachineInfoByEnvironmentBO> listMachines = machineDAO.listMachineByEnvironment(request.getEnvironmentId());
        for (ListMachineInfoByEnvironmentBO record : listMachines) {
            response.getMachines().add(ListMachineByEnvironmentRecord.builder()
                            .machineName(record.getMachineName())
                            .machineDesc(record.getMachineDesc())
                            .paramCount(record.getParamCount())
                            .fileCount(record.getFileCount())
                            .build()
            );
        }
        return response;
    }

}
